package com.example.artemis.statistics;

import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 消息统计模型
 * 封装消息处理的各项统计数据
 */
public class MessageStatistics {

    // 总计数据
    private final AtomicLong totalSent = new AtomicLong(0);
    private final AtomicLong totalProcessed = new AtomicLong(0);
    private final AtomicLong totalFailed = new AtomicLong(0);
    private final AtomicLong totalRetried = new AtomicLong(0);

    // 时间数据
    private final AtomicLong totalProcessingTime = new AtomicLong(0);
    private final AtomicLong totalProductionTime = new AtomicLong(0);
    private final AtomicLong minProcessingTime = new AtomicLong(Long.MAX_VALUE);
    private final AtomicLong maxProcessingTime = new AtomicLong(0);
    private final AtomicLong minProductionTime = new AtomicLong(Long.MAX_VALUE);
    private final AtomicLong maxProductionTime = new AtomicLong(0);

    // 创建时间
    private final LocalDateTime createdTime;

    public MessageStatistics() {
        this.createdTime = LocalDateTime.now();
    }

    // ================== 生产者统计 ==================

    /**
     * 增加发送消息计数
     */
    public void incrementSent(long count) {
        totalSent.addAndGet(count);
    }

    /**
     * 增加生产时间
     */
    public void addProductionTime(long time) {
        totalProductionTime.addAndGet(time);
        updateMinProductionTime(time);
        updateMaxProductionTime(time);
    }

    /**
     * 获取总发送消息数
     */
    public long getTotalSent() {
        return totalSent.get();
    }

    /**
     * 获取总生产时间
     */
    public long getTotalProductionTime() {
        return totalProductionTime.get();
    }

    /**
     * 获取平均生产时间
     */
    public double getAverageProductionTime() {
        long sent = totalSent.get();
        return sent > 0 ? (double) totalProductionTime.get() / sent : 0;
    }

    /**
     * 获取最小生产时间
     */
    public long getMinProductionTime() {
        long min = minProductionTime.get();
        return min == Long.MAX_VALUE ? 0 : min;
    }

    /**
     * 获取最大生产时间
     */
    public long getMaxProductionTime() {
        return maxProductionTime.get();
    }

    // ================== 消费者统计 ==================

    /**
     * 增加处理消息计数
     */
    public void incrementProcessed(long count) {
        totalProcessed.addAndGet(count);
    }

    /**
     * 增加失败消息计数
     */
    public void incrementFailed(long count) {
        totalFailed.addAndGet(count);
    }

    /**
     * 增加重试消息计数
     */
    public void incrementRetried(long count) {
        totalRetried.addAndGet(count);
    }

    /**
     * 增加处理时间
     */
    public void addProcessingTime(long time) {
        totalProcessingTime.addAndGet(time);
        updateMinProcessingTime(time);
        updateMaxProcessingTime(time);
    }

    /**
     * 获取总处理消息数
     */
    public long getTotalProcessed() {
        return totalProcessed.get();
    }

    /**
     * 获取总失败消息数
     */
    public long getTotalFailed() {
        return totalFailed.get();
    }

    /**
     * 获取总重试消息数
     */
    public long getTotalRetried() {
        return totalRetried.get();
    }

    /**
     * 获取总处理时间
     */
    public long getTotalProcessingTime() {
        return totalProcessingTime.get();
    }

    /**
     * 获取平均处理时间
     */
    public double getAverageProcessingTime() {
        long processed = totalProcessed.get();
        return processed > 0 ? (double) totalProcessingTime.get() / processed : 0;
    }

    /**
     * 获取最小处理时间
     */
    public long getMinProcessingTime() {
        long min = minProcessingTime.get();
        return min == Long.MAX_VALUE ? 0 : min;
    }

    /**
     * 获取最大处理时间
     */
    public long getMaxProcessingTime() {
        return maxProcessingTime.get();
    }

    // ================== 综合统计 ==================

    /**
     * 获取成功率（百分比）
     */
    public double getSuccessRate() {
        long total = totalProcessed.get() + totalFailed.get();
        return total > 0 ? (double) totalProcessed.get() / total * 100 : 0;
    }

    /**
     * 获取失败率（百分比）
     */
    public double getFailureRate() {
        long total = totalProcessed.get() + totalFailed.get();
        return total > 0 ? (double) totalFailed.get() / total * 100 : 0;
    }

    /**
     * 获取重试率（百分比）
     */
    public double getRetryRate() {
        long processed = totalProcessed.get();
        return processed > 0 ? (double) totalRetried.get() / processed * 100 : 0;
    }

    /**
     * 获取处理完成率（相对于发送数）
     */
    public double getCompletionRate() {
        long sent = totalSent.get();
        return sent > 0 ? (double) totalProcessed.get() / sent * 100 : 0;
    }

    /**
     * 获取统计创建时间
     */
    public LocalDateTime getCreatedTime() {
        return createdTime;
    }

    // ================== 私有辅助方法 ==================

    private void updateMinProcessingTime(long time) {
        long current;
        do {
            current = minProcessingTime.get();
        } while (time < current && !minProcessingTime.compareAndSet(current, time));
    }

    private void updateMaxProcessingTime(long time) {
        long current;
        do {
            current = maxProcessingTime.get();
        } while (time > current && !maxProcessingTime.compareAndSet(current, time));
    }

    private void updateMinProductionTime(long time) {
        long current;
        do {
            current = minProductionTime.get();
        } while (time < current && !minProductionTime.compareAndSet(current, time));
    }

    private void updateMaxProductionTime(long time) {
        long current;
        do {
            current = maxProductionTime.get();
        } while (time > current && !maxProductionTime.compareAndSet(current, time));
    }

    // ================== 重置和清空方法 ==================

    /**
     * 重置所有统计数据
     */
    public void reset() {
        totalSent.set(0);
        totalProcessed.set(0);
        totalFailed.set(0);
        totalRetried.set(0);
        totalProcessingTime.set(0);
        totalProductionTime.set(0);
        minProcessingTime.set(Long.MAX_VALUE);
        maxProcessingTime.set(0);
        minProductionTime.set(Long.MAX_VALUE);
        maxProductionTime.set(0);
    }

    // ================== 字符串表示 ==================

    @Override
    public String toString() {
        return String.format(
                "MessageStatistics{sent=%d, processed=%d, failed=%d, retried=%d, " +
                "avgProcessTime=%.2fms, avgProdTime=%.2fms, successRate=%.1f%%}",
                totalSent.get(), totalProcessed.get(), totalFailed.get(), totalRetried.get(),
                getAverageProcessingTime(), getAverageProductionTime(), getSuccessRate()
        );
    }

    /**
     * 获取详细统计报告
     */
    public String getDetailedReport() {
        StringBuilder report = new StringBuilder();
        report.append("=== 消息统计详细报告 ===\n");
        report.append(String.format("统计开始时间: %s\n", createdTime));
        report.append("\n生产者统计:\n");
        report.append(String.format("  总发送数: %d\n", totalSent.get()));
        report.append(String.format("  平均生产时间: %.2f ms\n", getAverageProductionTime()));
        report.append(String.format("  生产时间范围: %d - %d ms\n", getMinProductionTime(), getMaxProductionTime()));

        report.append("\n消费者统计:\n");
        report.append(String.format("  总处理数: %d\n", totalProcessed.get()));
        report.append(String.format("  总失败数: %d\n", totalFailed.get()));
        report.append(String.format("  总重试数: %d\n", totalRetried.get()));
        report.append(String.format("  平均处理时间: %.2f ms\n", getAverageProcessingTime()));
        report.append(String.format("  处理时间范围: %d - %d ms\n", getMinProcessingTime(), getMaxProcessingTime()));

        report.append("\n综合分析:\n");
        report.append(String.format("  成功率: %.2f%%\n", getSuccessRate()));
        report.append(String.format("  失败率: %.2f%%\n", getFailureRate()));
        report.append(String.format("  重试率: %.2f%%\n", getRetryRate()));
        report.append(String.format("  完成率: %.2f%%\n", getCompletionRate()));

        report.append("========================\n");
        return report.toString();
    }
}